home *** CD-ROM | disk | FTP | other *** search
- {.he Queue Maintenance Routines - %F}
- (********************************************************************)
- (* Queues *)
- (* *)
- (* Author: Geoff Moehrke *)
- (* Date: August 27, 1988 *)
- (* *)
- (* Purpose: Queue implementation, allows queueing of any data type *)
- (* using Turbo Pascal's generic pointers to reference *)
- (* queued data. *)
- (* *)
- (* Source: F:\TP\UNIT\QUEUES.PAS *)
- (********************************************************************)
- Unit Queues;
-
- interface
-
- type
- QueuePtr = ^QueueRec;
- QueueRec = record
- Data: Pointer; { Generic pointer to data }
- Next: QueuePtr; { Pointer to next QueueRec }
- end;
-
- Queue = record
- DataSize : Word; { Size of data in this queue }
- StartQ, { Pointer to beginning of queue }
- EndQ : QueuePtr; { Pointer to end of queue }
- Length, { Current length of queue }
- MaxLen : Word; { Maximum length queue reached so far }
- end;
-
- procedure InitQ ( Var Q: Queue; Size: Word );
- {- Initialize queue variables and set up for processing. }
- { Must be called for each queue before performing any operations }
- { on it. }
- { Example: InitQ ( MyQueue, SizeOf(MyType) ); }
-
-
- function Enqueue(Var Q:Queue; Item: Pointer): boolean;
- {- Add an item at end of queue, return True if successful. }
- { Parameters: Q - queue variable }
- { Item - generic pointer to item. easiest way is }
- { to use address operator (@AnyVar) }
- { }
- { Example: Enqueue( MyQueue, @MyVar); }
-
- function Dequeue(Var Q: Queue):Pointer;
- {- Returns a pointer to the first item in the queue, nil if }
- { queue is empty. }
- { }
- { Easiest way to access data after dequeueing is to use }
- { typecasting to the queued data type after checking for an }
- { empty queue. Example: }
- { }
- { If Not QEmpty(MyQueue) then }
- { IntVar := Integer( Dequeue(MyQueue)^ ); }
- { }
-
-
- function QEmpty(Q: Queue):Boolean;
- {- determine whether queue is empty or not }
-
- function QSize(Q: Queue):Word;
- {- returns current size (length) of queue }
-
- function MaxQSize(Q: Queue):Word;
- {- ruturns the maximum size (length) that Q has reached }
-
- implementation
-
- procedure InitQ(Var Q: Queue; Size: Word);
- {- Initialize queue variables and set up for processing }
-
- begin
- with Q do begin
- StartQ := nil;
- EndQ := nil;
- DataSize := Size;
- Length := 0;
- MaxLen := 0;
- end;
- end;
-
- {$F+}
- function HeapFunc( Size : Word ): Integer;
- {- Prevent New() or GetMem() from causing a run-time error if
- memory not available (See TP manual - Chapter 15). }
-
- begin
- HeapFunc := 1;
- end;
- {$F-}
-
-
- function Enqueue(Var Q:Queue; Item: Pointer): Boolean;
- {- Add an item at end of queue return true if successful }
-
- var NewItem, Temp:QueuePtr;
-
- begin
- Enqueue := False;
- New(NewItem);
- if NewItem = nil then
- Exit; { Insufficient memory }
- GetMem(NewItem^.Data,Q.DataSize);
- if NewItem^.Data = nil then
- Exit;
- Move(Item^,NewItem^.Data^,Q.DataSize);
- Temp := Q.EndQ;
- Q.EndQ := NewItem; { add new item at end }
- with Q do begin
- if Length = 0 then
- StartQ := NewItem;
- if Temp <> nil then
- Temp^.Next := EndQ;
- EndQ^.Next := nil;
- inc(Length); { increment the length }
- if Length > MaxLen then { adjust max length }
- MaxLen := Length;
- Enqueue := True;
- end
- end;
-
- function Dequeue(Var Q: Queue):Pointer;
- {- Returns a pointer to the first item in the queue, nil if queue is empty }
-
- var Temp : QueuePtr;
-
- begin
- Dequeue := nil;
- if Q.Length = 0 then { queue is empty - exit w/nil pointer }
- exit;
- with Q do begin
- Dec(Length);
- Dequeue := StartQ^.Data;
- FreeMem(StartQ^.Data,Q.DataSize);
- Temp := StartQ;
- StartQ := StartQ^.Next;
- If Length = 0 then
- EndQ := nil;
- end;
- end;
-
- function QEmpty(Q: Queue):Boolean;
- {- determine whether queue is empty or not }
-
- begin
- QEmpty := Q.Length=0;
- end;
-
- function QSize(Q: Queue):Word;
- {- returns current size of queue }
-
- begin
- QSize := Q.Length;
- end;
-
- function MaxQSize(Q: Queue):Word;
- {- returns maximum length Q has reached }
-
- begin
- MaxQSize := Q.MaxLen;
- end;
-
-
- end. { Unit Queues }